package cn.turboinfo.fuyang.api.domain.mini.usecase.activity;

import cn.turboinfo.fuyang.api.domain.common.service.activity.ActivityApplyService;
import cn.turboinfo.fuyang.api.domain.common.service.activity.ActivityService;
import cn.turboinfo.fuyang.api.domain.common.service.user.SysUserService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.entity.common.enumeration.user.UserType;
import cn.turboinfo.fuyang.api.entity.common.pojo.activity.Activity;
import cn.turboinfo.fuyang.api.entity.common.pojo.activity.ActivityApplyCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.user.SysUser;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.time.LocalDateTime;

/**
 * 消费者活动报名
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class MiniConsumerActivityApplyUseCase extends AbstractUseCase<MiniConsumerActivityApplyUseCase.InputData, MiniConsumerActivityApplyUseCase.OutputData> {
    private final ActivityApplyService activityApplyService;
    private final ActivityService activityService;

    private final SysUserService sysUserService;

    @Override
    protected OutputData doAction(InputData inputData) {

        Long activityId = inputData.getActivityId();
        Long userId = inputData.getUserId();
        LocalDateTime now = LocalDateTime.now();

        Activity activity = activityService.getByIdEnsure(activityId);

        if (activity.getStartTime() != null && activity.getStartTime().isAfter(now)) {
            throw new RuntimeException("活动未开始");
        }

        if (activity.getEndTime() != null && activity.getEndTime().isBefore(now)) {
            throw new RuntimeException("活动已结束");
        }

        if (!activity.getActivityScope().contains(UserType.Consumer)) {
            throw new RuntimeException("活动不支持消费者报名");
        }

        if (activity.getApplied() >= activity.getLimitNum()) {
            throw new RuntimeException("报名人数已满");
        }

        activityApplyService.findByActivityIdAndUserId(activityId, userId, UserType.Consumer).ifPresent(activityApply -> {
            throw new RuntimeException("已报名，不能重复报名");
        });

        SysUser user = sysUserService.getByIdEnsure(userId);

        ActivityApplyCreator.Builder builder = ActivityApplyCreator.builder()
                .withActivityId(activityId)
                .withUserId(userId)
                .withUserName(user.getUsername())
                .withUseMobile(user.getMobile())
                .withUserType(UserType.Consumer);

        activityApplyService.save(builder.build());

        return OutputData.builder()
                .build();
    }

    @EqualsAndHashCode(
            callSuper = true
    )
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        @NotNull
        @Positive
        private Long activityId;

        /**
         * 用户ID
         */
        @NotNull(message = "用户ID不能为空")
        @Positive
        private Long userId;
    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {


    }
}
